using System;

namespace WIT.Global;

/// <summary>
/// 新能源行业国标编码帮助类
/// </summary>
public class NationalStandardHelper
{
	/// <summary>
	/// 生成24位国标SN
	/// </summary>
	/// <param name="manufacturerCode">第1-3位：厂商代码</param>
	/// <param name="productTypeCode">第4位：产品类型代码（电池包P/模组M/电芯C）</param>
	/// <param name="batteryTypeCode">第5位：电池类型代码（镍氢A/磷酸铁锂B/锰酸锂C/钴酸锂D/三元E/超级电容器F/钛酸锂G/其它Z）</param>
	/// <param name="specCode">第6-7位：规格代码（区分产品型号）</param>
	/// <param name="traceCode">第8-13位：追溯信息码（区分产品型号）</param>
	/// <param name="addrCode">第14位：工厂地址代码</param>
	/// <param name="productionLineCode">第18-19位：产线编码</param>
	/// <param name="serialCode">第20-24位：5位流水号</param>
	/// <returns></returns>
	public static string GenerateModuleSN(string manufacturerCode, string productTypeCode, string batteryTypeCode, string specCode, string traceCode, string addrCode, string productionLineCode, string serialCode)
	{
		DateTime now = DateTime.Now;
		string text = TransformYearCode(now.Year);
		string text2 = TransformMonthCode(now.Month);
		string text3 = TransformDayCode(now.Day);
		string text4 = text + text2 + text3;
		return manufacturerCode + productTypeCode + batteryTypeCode + specCode + traceCode + addrCode + text4 + productionLineCode + serialCode;
	}

	/// <summary>
	/// 生成24位国标SN
	/// </summary>
	/// <param name="manufacturerCode">第1-3位：厂商代码</param>
	/// <param name="productTypeCode">第4位：产品类型代码（电池包P/模组M/电芯C）</param>
	/// <param name="batteryTypeCode">第5位：电池类型代码（镍氢A/磷酸铁锂B/锰酸锂C/钴酸锂D/三元E/超级电容器F/钛酸锂G/其它Z）</param>
	/// <param name="specCode">第6-7位：规格代码（区分产品型号）</param>
	/// <param name="traceCode">第8-13位：追溯信息码（区分产品型号）</param>
	/// <param name="addrCode">第14位：工厂地址代码</param>
	/// <param name="dateCode">第15-17位：日期编码</param>
	/// <param name="productionLineCode">第18-19位：产线编码</param>
	/// <param name="serialCode">第20-24位：5位流水号</param>
	/// <returns></returns>
	public static string GenerateModuleSN(string manufacturerCode, string productTypeCode, string batteryTypeCode, string specCode, string traceCode, string addrCode, string dateCode, string productionLineCode, string serialCode)
	{
		return manufacturerCode + productTypeCode + batteryTypeCode + specCode + traceCode + addrCode + dateCode + productionLineCode + serialCode;
	}

	/// <summary>
	/// 生成日期代码
	/// </summary>
	/// <param name="time">指定时间</param>
	/// <returns></returns>
	public static string GenerateDateCode(DateTime time)
	{
		string text = TransformYearCode(time.Year);
		string text2 = TransformMonthCode(time.Month);
		string text3 = TransformDayCode(time.Day);
		return text + text2 + text3;
	}

	/// <summary>
	/// 转换得到年份代码
	/// </summary>
	/// <param name="year"></param>
	private static string TransformYearCode(int year)
	{
		string empty = string.Empty;
		int num = year - 2010;
		if (num >= 1 && num <= 15)
		{
			empty = Convert.ToString(num, 16);
		}
		else if (num >= 16)
		{
			switch (num)
			{
			case 16:
				empty = "G";
				break;
			case 17:
				empty = "H";
				break;
			case 18:
				empty = "J";
				break;
			case 19:
				empty = "K";
				break;
			case 20:
				empty = "L";
				break;
			case 21:
				empty = "M";
				break;
			case 22:
				empty = "N";
				break;
			case 23:
				empty = "P";
				break;
			case 24:
				empty = "R";
				break;
			case 25:
				empty = "S";
				break;
			case 26:
				empty = "T";
				break;
			case 27:
				empty = "V";
				break;
			case 28:
				empty = "W";
				break;
			case 29:
				empty = "X";
				break;
			case 30:
				empty = "Y";
				break;
			default:
				num -= 30;
				empty = TransformYearCode(num);
				break;
			}
		}
		else
		{
			empty = "YearCodeError";
		}
		return empty.ToUpper();
	}

	/// <summary>
	/// 转换得到月份代码
	/// </summary>
	/// <param name="month"></param>
	private static string TransformMonthCode(int month)
	{
		return Convert.ToString(DateTime.Now.Month, 16).ToUpper().ToUpper();
	}

	/// <summary>
	/// 转换得到日代码
	/// </summary>
	/// <param name="day"></param>
	/// <returns></returns>
	private static string TransformDayCode(int day)
	{
		string empty = string.Empty;
		empty = ((day >= 1 && day <= 15) ? Convert.ToString(day, 16) : ((day < 16) ? "DayCodeError" : (day switch
		{
			16 => "G", 
			17 => "H", 
			18 => "J", 
			19 => "K", 
			20 => "L", 
			21 => "M", 
			22 => "N", 
			23 => "P", 
			24 => "R", 
			25 => "S", 
			26 => "T", 
			27 => "V", 
			28 => "W", 
			29 => "X", 
			30 => "Y", 
			31 => "0", 
			_ => "DayCodeError", 
		})));
		return empty.ToUpper();
	}
}
